package com.heima.comment.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.heima.comment.pojos.entity.*;
import com.heima.comment.pojos.vos.ApCommentRepayVo;
import com.heima.comment.service.CommentRepayService;
import com.heima.common.constants.WemediaConstants;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepayListDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.utils.thread.ThreadLocalUtil;
import com.heima.verify.service.impl.VerifyMaterialServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private VerifyMaterialServiceImpl verifyMaterialServicel;
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        //1.校验参数
        if (ThreadLocalUtil.get() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (StringUtils.isEmpty(dto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_EMPTY);
        }
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论内容限制在140字");
        }
        Map auditContent = verifyMaterialServicel.VerifyText(dto.getContent());
        Integer type = (Integer) auditContent.get("conclusionType");
        if (type != WemediaConstants.WM_CHECK_PASS) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_AUDIT_NOT_ALLOW);
        }

        //封装数据
        ApCommentRepay apCommentRepay = new ApCommentRepay(IdWorker.getId());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setAuthorName("临时用户");
        apCommentRepay.setContent(dto.getContent());
        //插入数据库
        mongoTemplate.save(apCommentRepay);

        //更新评论的回复表
        updateReply(dto.getCommentId());

        //更新评论点赞表
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 更新评论的回复表
     * @param commentId
     */
    private void updateReply(Long commentId) {
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(commentId)), ApComment.class);
        apComment.setReply(apComment.getReply() == null ? 1 : apComment.getReply() + 1);
        mongoTemplate.save(apComment);
    }

    /**
     * 加载评论回复列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayListDto dto) {
        //1.检查参数
        if(dto == null || dto.getCommentId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        int size = 20;

        //2.加载数据
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()));
        query.with(Sort.by(Sort.Direction.DESC,"createdTime")).limit(size);
        List<ApCommentRepay> list = mongoTemplate.find(query, ApCommentRepay.class);

        //3.数据封装返回
        //3.1 用户未登录
        Integer userId = ThreadLocalUtil.get();
        if(userId == null){
            return ResponseResult.okResult(list);
        }

        //3.2 用户已登录

        //需要查询当前评论中哪些数据被点赞了
        List<Long> idList = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentRepayId").in(idList).and("authorId").is(userId));
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(query1, ApCommentRepayLike.class);
        if(apCommentRepayLikes == null || apCommentRepayLikes.size() == 0 ){
            return ResponseResult.okResult(list);
        }

        List<ApCommentRepayVo> resultList = new ArrayList<>();
        list.forEach(x->{
            ApCommentRepayVo vo = new ApCommentRepayVo();
            BeanUtils.copyProperties(x,vo);
            for (ApCommentRepayLike apCommentRepayLike : apCommentRepayLikes) {
                if(x.getId().equals(apCommentRepayLike.getCommentRepayId())){
                    vo.setOperation((short)0);
                    break;
                }
            }
            resultList.add(vo);
        });

        return ResponseResult.okResult(resultList);
    }

    /**
     * 点赞回复的评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        if (ThreadLocalUtil.get() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto == null || dto.getCommentRepayId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //更新回复评论的点赞数量
        ApCommentRepay apCommentRepay = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(dto.getCommentRepayId())), ApCommentRepay.class);
        if (dto.getOperation() == 0){
            apCommentRepay.setLikes(apCommentRepay.getLikes() == null ? 1 : apCommentRepay.getLikes() + 1);
        } else if (dto.getOperation() == 1){
            apCommentRepay.setLikes(apCommentRepay.getLikes() - 1);
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        mongoTemplate.save(apCommentRepay);

        //更新评论点赞和用户的关系
        ApCommentRepayLike apCommentRepayLike = mongoTemplate.findOne(Query.query(Criteria.where("commentRepayId").is(dto.getCommentRepayId()).and("authorId").is(ThreadLocalUtil.get())), ApCommentRepayLike.class);
        if (apCommentRepayLike == null) {
            apCommentRepayLike = new ApCommentRepayLike(IdWorker.getId());
            apCommentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            apCommentRepayLike.setAuthorId(ThreadLocalUtil.get());
        }
        apCommentRepayLike.setOperation(dto.getOperation());
        mongoTemplate.save(apCommentRepayLike);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
